package com.ocm.tourism.web;

import java.awt.Dimension;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.util.UriUtils;
import org.springframework.web.util.WebUtils;

import com.ocm.tourism.core.domain.Advertisement;
import com.ocm.tourism.core.domain.Business;
import com.ocm.tourism.core.domain.BusinessType;
import com.ocm.tourism.core.domain.CommonItems;
import com.ocm.tourism.core.domain.FileInfo;
import com.ocm.tourism.core.domain.Priority;
import com.ocm.tourism.core.domain.SaleOff;
import com.ocm.tourism.core.domain.ScheduleTour;
import com.ocm.tourism.core.service.CommonItemsService;
import com.ocm.tourism.core.service.ScheduleTourService;
import com.ocm.tourism.core.user.BusinessServiceClient;
import com.ocm.tourism.file.MimeTypeSupport;
import com.ocm.tourism.file.SimpleImageInfo;
import com.ocm.tourism.web.util.FileInfoUtil;

@RequestMapping("/touristAgency")
@Controller
@SessionAttributes("sessionErrorObjects")
public class TouristAgencyController {

   private final static String SESSION_ERROROBJECTS="sessionErrorObjects";

   @Autowired
   ScheduleTourService scheduleTourService;

   @Autowired
   BusinessServiceClient businessServiceClient;

   @Autowired
   CommonItemsService commonItemsService;

   @Autowired
   FileInfoUtil fileInfoUtil;

   @InitBinder
   public void initBinder(WebDataBinder binder) {
        binder.initDirectFieldAccess();
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
        dateFormat.setLenient(false);
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
    }

   @RequestMapping(value = "/view")
   public String viewNew(Model uiModel, SessionStatus sessionStatus) {
      sessionStatus.setComplete();
      uiModel.addAttribute("submenuSelected", "tour");
      return "touristAgency/view";
   }

   @RequestMapping(value = "/create", method = RequestMethod.GET)
   public String createForm(Model uiModel) {
      Business business = new Business();
      business.setBusinessType(BusinessType.TOURISTAGENCY);
      populateEditForm(uiModel, business);
      return "touristAgency/create";
   }

   @RequestMapping(value = "/{id}", method = RequestMethod.GET)
   public String showAgency(@PathVariable("id")Long agencyId, Model uiModel, SessionStatus sessionStatus) {
      sessionStatus.setComplete();
      uiModel.addAttribute("agencyId", agencyId);
      return "touristAgency/show";
   }

   @RequestMapping(value = "/{id}/update", method = RequestMethod.GET)
   public String updateAgency(@PathVariable("id")Long agencyId,Model uiModel) {
      uiModel.addAttribute("agencyId", agencyId);
      uiModel.addAttribute("selected", "info");
      uiModel.addAttribute("selectedUrl", "/touristAgency/"+agencyId+"/update/form");
      return "touristAgency/show";
   }
   
   @RequestMapping(value = "/{id}/update/form", method = RequestMethod.GET)
   public String updateAgencyForm(@PathVariable("id")Long agencyId, Model uiModel, SessionStatus sessionStatus) {
      this.businessServiceClient.validatedAcceptBusiness(agencyId);
      Object sess = null;
      if (uiModel.containsAttribute(SESSION_ERROROBJECTS) && uiModel.asMap().get(SESSION_ERROROBJECTS) != null){
         Model ssUIModel = (Model) uiModel.asMap().get(SESSION_ERROROBJECTS);
         uiModel.addAllAttributes(ssUIModel.asMap());
         sess = uiModel.asMap().get("agency");
         sessionStatus.setComplete();
      }
      Business business = sess != null ? (Business) sess : this.scheduleTourService.findTouristAgency(agencyId);
      populateEditForm(uiModel, business);
      return "touristAgency/update";
   }

   @RequestMapping(value = "/{id}/info", method = RequestMethod.GET)
   public String showAgencyInfo(@PathVariable("id")Long agencyId,Model uiModel) {
      uiModel.addAttribute("itemId", agencyId);
      Business business = this.scheduleTourService.findTouristAgency(agencyId);
      uiModel.addAttribute("business", business);
      return "touristAgency/showInfo";
   }

   @RequestMapping(produces = "text/html", method=RequestMethod.GET)
   public String list(@RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size, Model uiModel) {
       long count = businessServiceClient.countTouristAgencies();
       if (page != null || size != null) {
           int sizeNo = size == null ? 10 : size.intValue();
           final int firstResult = page == null ? 0 : (page.intValue() - 1) * sizeNo;
           uiModel.addAttribute("touristAgencies", businessServiceClient.findTouristAgencies(firstResult, sizeNo));
           float nrOfPages = (float) count / sizeNo;
           uiModel.addAttribute("maxPages", (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages));
       } else {
           List<Business> touristAgencies = count == 0 ? new ArrayList<Business>() : businessServiceClient.findTouristAgencies(0, 25);
           uiModel.addAttribute("touristAgencies", touristAgencies);
       }
       return "touristAgency/list";
   }

   @RequestMapping(value="/update", method = RequestMethod.POST)
   public String update(@Valid Business business, @RequestParam("fileData")CommonsMultipartFile commonsMultipartFile, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest, SessionStatus sessionStatus) throws Exception {
      this.businessServiceClient.validatedAcceptBusiness(business.getId());
      validate(commonsMultipartFile, uiModel, bindingResult);
      if (bindingResult.hasErrors()) {
         uiModel.addAttribute("agencyId", business.getId());
         uiModel.addAttribute("selected", "info");
         uiModel.addAttribute("selectedUrl", "/touristAgency/"+business.getId()+"/update/form");
         uiModel.addAttribute(SESSION_ERROROBJECTS, uiModel);
         return "touristAgency/update";
      }
      Business actual = this.scheduleTourService.findTouristAgency(business.getId());
      if (commonsMultipartFile.getSize() > 0){
         String uploadDir = httpServletRequest.getSession().getServletContext().getInitParameter("uploadDir");
         String folderPath = fileInfoUtil.createContainer(uploadDir);
         FileInfo fileInfo = fileInfoUtil.writeFile(commonsMultipartFile, uploadDir, folderPath);
         business.setAvatar(fileInfo);
      }else{
         business.setAvatar(actual.getAvatar());
      }
      uiModel.asMap().clear();
      sessionStatus.setComplete();
      business.setParticipant(actual.getParticipant());
      this.scheduleTourService.saveTouristAgency(business);
      return "redirect:/touristAgency/" + encodeUrlPathSegment(business.getId().toString(), httpServletRequest);
   }

   @RequestMapping(method = RequestMethod.POST)
   public String create(@Valid Business business, @RequestParam("fileData")CommonsMultipartFile commonsMultipartFile, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
      validate(commonsMultipartFile, uiModel, bindingResult);
      if (bindingResult.hasErrors()) {
         populateEditForm(uiModel, business);
         return "touristAgency/create";
      }
      if (commonsMultipartFile.getSize() > 0){
         String uploadDir = httpServletRequest.getSession().getServletContext().getInitParameter("uploadDir");
         String folderPath = fileInfoUtil.createContainer(uploadDir);
         FileInfo fileInfo = fileInfoUtil.writeFile(commonsMultipartFile, uploadDir, folderPath);
         business.setAvatar(fileInfo);
      }
      uiModel.asMap().clear();
      this.scheduleTourService.saveTouristAgency(business);
      return "redirect:/touristAgency?page=1&size=25";
   }

   @RequestMapping(value = "/{id}/tour/list", method = RequestMethod.GET)
   public String listTours(@PathVariable("id")Long agencyId,Model uiModel) {
      uiModel.addAttribute("agencyId", agencyId);
      uiModel.addAttribute("selected", "tour");
      uiModel.addAttribute("selectedUrl", "/touristAgency/"+agencyId+"/tour?page=1&size=25");
      return "touristAgency/show";
   }
   
   @RequestMapping(value = "/tour/{tourId}/detail", method = RequestMethod.GET)
   public String viewAgencyDetail(@PathVariable("tourId")Long tourId,Model uiModel) {
      ScheduleTour scheduleTour = this.scheduleTourService.findScheduleTour(tourId);
      uiModel.addAttribute("tour", scheduleTour);
      uiModel.addAttribute("itemId", tourId);
      return "touristAgency/tour/detail";
   }

   @RequestMapping(value = "/{id}/tour/{tourId}", method = RequestMethod.GET)
   public String showTour(@PathVariable("id")Long agencyId,@PathVariable("tourId")Long tourId,Model uiModel) {
      uiModel.addAttribute("agencyId", agencyId);
      uiModel.addAttribute("selected", "tour");
      uiModel.addAttribute("selectedUrl", "/touristAgency/"+agencyId+"/tour/"+tourId+"/form");
      return "touristAgency/show";
   }

   @RequestMapping(value = "/{id}/tour/{tourId}/form", method = RequestMethod.GET)
   public String showTourForm(@PathVariable("id")Long agencyId,@PathVariable("tourId")Long tourId,Model uiModel) {
      this.businessServiceClient.validatedAcceptBusiness(agencyId);
      ScheduleTour scheduleTour = this.scheduleTourService.findScheduleTour(tourId);
      uiModel.addAttribute("tour", scheduleTour);
      uiModel.addAttribute("itemId", tourId);
      uiModel.addAttribute("agencyId", agencyId);
      return "touristAgency/tour/show";
   }

   @RequestMapping(value="/{id}/tour", produces = "text/html", method=RequestMethod.GET)
   public String listTours(@PathVariable("id")Long agencyId, @RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size, Model uiModel) {
      this.businessServiceClient.validatedAcceptBusiness(agencyId);
       long count = scheduleTourService.countTours(agencyId);
       if (page != null || size != null) {
           int sizeNo = size == null ? 10 : size.intValue();
           final int firstResult = page == null ? 0 : (page.intValue() - 1) * sizeNo;
           uiModel.addAttribute("scheduleTours", scheduleTourService.findTours(agencyId, firstResult, sizeNo));
           float nrOfPages = (float) count / sizeNo;
           uiModel.addAttribute("maxPages", (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages));
       } else {
           List<ScheduleTour> scheduleTours = count == 0 ? new ArrayList<ScheduleTour>() : scheduleTourService.findTours(agencyId, 0, 25);
           uiModel.addAttribute("scheduleTours", scheduleTours);
       }
       uiModel.addAttribute("itemId", agencyId);
       return "touristAgency/tour/list";
   }

   @RequestMapping(value = "/{id}/tour/create", method = RequestMethod.GET)
   public String createTour(@PathVariable("id")Long agencyId,Model uiModel) {
      uiModel.addAttribute("agencyId", agencyId);
      uiModel.addAttribute("selected", "tour");
      uiModel.addAttribute("selectedUrl", "/touristAgency/"+agencyId+"/tour/create/form");
      uiModel.addAttribute(SESSION_ERROROBJECTS, uiModel);
      return "touristAgency/show";
   }

   @RequestMapping(value = "/{id}/tour/create/form", method = RequestMethod.GET)
   public String createTourForm(@PathVariable("id")Long agencyId,Model uiModel, SessionStatus sessionStatus) {
      this.businessServiceClient.validatedAcceptBusiness(agencyId);
      uiModel.addAttribute("itemId", agencyId);
      ScheduleTour scheduleTour = null;
      if (uiModel.containsAttribute(SESSION_ERROROBJECTS) && uiModel.asMap().get(SESSION_ERROROBJECTS) != null){
         Model ssUIModel = (Model) uiModel.asMap().get(SESSION_ERROROBJECTS);
         uiModel.addAllAttributes(ssUIModel.asMap());
         Object sess = uiModel.asMap().get("scheduleTour");
         if (sess != null){
            scheduleTour = (ScheduleTour) sess;
            scheduleTour.setTransport(null);
         }
         sessionStatus.setComplete();
      }
      populateTourEditForm(uiModel, scheduleTour==null?new ScheduleTour() : scheduleTour);
      return "touristAgency/tour/create";
   }
   
   @RequestMapping(value = "/{id}/tour",method = RequestMethod.POST)
   public String saveTour(@PathVariable("id")Long agencyId, @RequestParam("fileData")CommonsMultipartFile commonsMultipartFile, @Valid ScheduleTour scheduleTour, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
      this.businessServiceClient.validatedAcceptBusiness(agencyId);
      scheduleTour.setId(null);
      validate(commonsMultipartFile, uiModel, bindingResult);
      if (bindingResult.hasErrors()) {
         return createTour(agencyId, uiModel);
      }
      if (commonsMultipartFile.getSize() > 0){
         String uploadDir = httpServletRequest.getSession().getServletContext().getInitParameter("uploadDir");
         String folderPath = fileInfoUtil.createContainer(uploadDir);
         FileInfo fileInfo = fileInfoUtil.writeFile(commonsMultipartFile, uploadDir, folderPath);
         scheduleTour.setAvatar(fileInfo);
      }
      uiModel.asMap().clear();
      Business business = this.scheduleTourService.findTouristAgency(agencyId);
      scheduleTour.setBusiness(business);
      this.scheduleTourService.saveScheduleTour(scheduleTour);
      return "redirect:/touristAgency/"+agencyId+"/tour/list";
   }

   @RequestMapping(value = "/{id}/tour/{tourId}/update", method = RequestMethod.GET)
   public String showUpdateTour(@PathVariable("id")Long agencyId,@PathVariable("tourId")Long tourId,Model uiModel) {
      uiModel.addAttribute("agencyId", agencyId);
      uiModel.addAttribute("selected", "tour");
      uiModel.addAttribute("selectedUrl", "/touristAgency/"+agencyId+"/tour/"+tourId+"/update/form");
      return "touristAgency/show";
   }

   @RequestMapping(value = "/{id}/tour/{tourId}/update/form", method = RequestMethod.GET)
   public String showUpdateTourForm(@PathVariable("id")Long agencyId,@PathVariable("tourId")Long tourId,Model uiModel, SessionStatus sessionStatus) {
      this.businessServiceClient.validatedAcceptBusiness(agencyId);
      ScheduleTour scheduleTour = null;
      if (uiModel.containsAttribute(SESSION_ERROROBJECTS) && uiModel.asMap().get(SESSION_ERROROBJECTS) != null){
         Model ssUIModel = (Model) uiModel.asMap().get(SESSION_ERROROBJECTS);
         uiModel.addAllAttributes(ssUIModel.asMap());
         Object sess = uiModel.asMap().get("scheduleTour");
         scheduleTour = sess == null ? new ScheduleTour() : (ScheduleTour) sess;
         sessionStatus.setComplete();
      }else {
         scheduleTour = this.scheduleTourService.findScheduleTour(tourId);
      }
      populateTourEditForm(uiModel, scheduleTour);
      uiModel.addAttribute("itemId", agencyId);
      return "touristAgency/tour/update";
   }

   @RequestMapping(value="/{id}/tour/{tourid}/update", method = RequestMethod.POST)
   public String updateTour(@PathVariable("id")Long agencyId,@PathVariable("tourid")Long tourId, @RequestParam("fileData")CommonsMultipartFile commonsMultipartFile, @Valid ScheduleTour scheduleTour, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest, SessionStatus sessionStatus) throws Exception {
      this.businessServiceClient.validatedAcceptBusiness(agencyId);
      scheduleTour.setId(tourId);
      validate(commonsMultipartFile, uiModel, bindingResult);
      if (bindingResult.hasErrors()) {
         uiModel.addAttribute(SESSION_ERROROBJECTS, uiModel);
         return showUpdateTour(agencyId, tourId, uiModel);
      }
      if (commonsMultipartFile.getSize() > 0){
         String uploadDir = httpServletRequest.getSession().getServletContext().getInitParameter("uploadDir");
         String folderPath = fileInfoUtil.createContainer(uploadDir);
         FileInfo fileInfo = fileInfoUtil.writeFile(commonsMultipartFile, uploadDir, folderPath);
         scheduleTour.setAvatar(fileInfo);
      }else{
         ScheduleTour actual = this.scheduleTourService.findScheduleTour(tourId);
         scheduleTour.setAvatar(actual.getAvatar());
      }
      uiModel.asMap().clear();
      sessionStatus.setComplete();
      Business business = this.scheduleTourService.findTouristAgency(agencyId);
      scheduleTour.setBusiness(business);
      this.scheduleTourService.saveScheduleTour(scheduleTour);
      return "redirect:/touristAgency/" + encodeUrlPathSegment(agencyId.toString(), httpServletRequest) + "/tour/"+encodeUrlPathSegment(tourId.toString(), httpServletRequest);
   }

   @RequestMapping(value="{agencyId}/tour/{tourId}", method = RequestMethod.DELETE)
   public String deleteTour(@PathVariable("agencyId")Long agencyId, @PathVariable("tourId")Long tourId,Model uiModel,HttpServletRequest httpServletRequest) throws Exception {
      this.businessServiceClient.validatedAcceptBusiness(agencyId);
      this.scheduleTourService.deleteScheduleTour(tourId);
      return "redirect:/touristAgency/"+encodeUrlPathSegment(agencyId.toString(), httpServletRequest)+"/tour/list";
   }
   
   @RequestMapping(value="/{agencyId}/saleoff/tour/list", produces = "text/html", method=RequestMethod.GET)
   public String listTourSaleOff(@PathVariable("agencyId")Long agencyId, Model uiModel) {
      uiModel.addAttribute("agencyId", agencyId);
      uiModel.addAttribute("selected", "saleoff");
      uiModel.addAttribute("selectedUrl", "/touristAgency/"+agencyId+"/saleoff/tour");
      return "touristAgency/show";
   }

   @RequestMapping(value="/{agencyId}/saleoff/tour", produces = "text/html", method=RequestMethod.GET)
   public String listTourSaleOffForm(@PathVariable("agencyId")Long agencyId, @RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size, Model uiModel) {
       listTours(agencyId, page, size, uiModel);
       return "touristAgency/saleoff/tour";
   }

   @RequestMapping(value="/{agencyId}/saleoff/tour/{tourId}", produces = "text/html", method=RequestMethod.GET)
   public String showTourSaleOff(@PathVariable("agencyId")Long agencyId,@PathVariable("tourId")Long tourId, @RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size, Model uiModel) {
      uiModel.addAttribute("agencyId", agencyId);
      uiModel.addAttribute("selected", "saleoff");
      uiModel.addAttribute("selectedUrl", "/touristAgency/"+agencyId+"/saleoff/tour/"+tourId+"/form");
      return "touristAgency/show";
   }
   
   @RequestMapping(value="/{agencyId}/saleoff/tour/{tourId}/form", produces = "text/html", method=RequestMethod.GET)
   public String showTourSaleOffForm(@PathVariable("agencyId")Long agencyId,@PathVariable("tourId")Long tourId, @RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size, Model uiModel) {
      this.businessServiceClient.validatedAcceptBusiness(agencyId);
      ScheduleTour scheduleTour = this.scheduleTourService.findScheduleTour(tourId);
      uiModel.addAttribute("scheduleTour", scheduleTour);
      uiModel.addAttribute("saleoff", scheduleTour.getSaleOff());
      uiModel.addAttribute("agencyId", agencyId);
      uiModel.addAttribute("itemId", tourId);
      return "touristAgency/saleoff/tour/show";
   }
   
   @RequestMapping(value = "{agencyId}/saleoff/tour/{id}/update", method = RequestMethod.GET)
   public String createTourSaleOff(@PathVariable("agencyId")Long agencyId, @PathVariable("id")Long tourId,Model uiModel) {
      uiModel.addAttribute("agencyId", agencyId);
      uiModel.addAttribute("selected", "saleoff");
      uiModel.addAttribute("selectedUrl", "/touristAgency/"+agencyId+"/saleoff/tour/"+tourId+"/update/form");
      return "touristAgency/show";
   }

   @RequestMapping(value = "{agencyId}/saleoff/tour/{tourId}/update/form", method = RequestMethod.GET)
   public String createTourSaleOffForm(@PathVariable("agencyId")Long agencyId, @PathVariable("tourId")Long tourId,Model uiModel, SessionStatus sessionStatus) {
      this.businessServiceClient.validatedAcceptBusiness(agencyId);
      uiModel.addAttribute("itemId", tourId);
      uiModel.addAttribute("agencyId", agencyId);
      SaleOff saleOff = null;
      if (uiModel.containsAttribute(SESSION_ERROROBJECTS) && uiModel.asMap().get(SESSION_ERROROBJECTS) != null){
         Model ssUIModel = (Model) uiModel.asMap().get(SESSION_ERROROBJECTS);
         uiModel.addAllAttributes(ssUIModel.asMap());
         Object sess = uiModel.asMap().get("saleoff");
         if (sess != null){
            saleOff = (SaleOff) sess;
         }
         sessionStatus.setComplete();
      }
      ScheduleTour scheduleTour = this.scheduleTourService.findScheduleTour(tourId);
      uiModel.addAttribute("tour", scheduleTour);
      uiModel.addAttribute("tourId", tourId);
      saleOff = (saleOff==null)?scheduleTour.getSaleOff():saleOff;
      populateSaleOffEditForm(uiModel, saleOff==null?new SaleOff() : saleOff);
      return "touristAgency/saleoff/tour/update";
   }
   
   @RequestMapping(value="{agencyId}/saleoff/tour/{tourId}", method = RequestMethod.PUT)
   public String updateTourSaleOff(@PathVariable("agencyId")Long agencyId, @PathVariable("tourId")Long tourId,@Valid SaleOff saleoff, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest, SessionStatus sessionStatus) throws Exception {
      this.businessServiceClient.validatedAcceptBusiness(agencyId);
      if (bindingResult.hasErrors()) {
         uiModel.addAttribute(SESSION_ERROROBJECTS, uiModel);
         return createTourSaleOff(agencyId, tourId, uiModel);
      }
      
      uiModel.asMap().clear();
      sessionStatus.setComplete();
      ScheduleTour scheduleTour = this.scheduleTourService.findScheduleTour(tourId);
      saleoff.setScheduleTour(scheduleTour);
      saleoff.setModifiedDate(new Date(System.currentTimeMillis()));
      scheduleTour.setSaleOff(saleoff);
      this.scheduleTourService.saveScheduleTour(scheduleTour);
      return "redirect:/touristAgency/"+encodeUrlPathSegment(agencyId.toString(), httpServletRequest)+"/saleoff/tour/list";
   }
   
   @RequestMapping(value="{agencyId}/saleoff/tour/{tourId}", method = RequestMethod.DELETE)
   public String deleteTourSaleOff(@PathVariable("agencyId")Long agencyId, @PathVariable("tourId")Long tourId,Model uiModel,HttpServletRequest httpServletRequest) throws Exception {
      this.businessServiceClient.validatedAcceptBusiness(agencyId);
      ScheduleTour scheduleTour = this.scheduleTourService.findScheduleTour(tourId);
      scheduleTour.setSaleOff(null);
      this.scheduleTourService.saveScheduleTour(scheduleTour);
      return "redirect:/touristAgency/"+encodeUrlPathSegment(agencyId.toString(), httpServletRequest)+"/saleoff/tour/list";
   }

   @RequestMapping(value="{agencyId}/advertisement")
   public String viewAdvs(@PathVariable("agencyId")Long agencyId, Model uiModel){
      uiModel.addAttribute("agencyId", agencyId);
      uiModel.addAttribute("selected", "advertisement");
      uiModel.addAttribute("selectedUrl", "/touristAgency/"+agencyId+"/advertisement/list?page=1&size=25");
      return "touristAgency/show";
   }

   @RequestMapping(value="{agencyId}/advertisement/list")
   public String viewAdvsForm(@PathVariable("agencyId")Long agencyId, @RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size, Model uiModel){
      long count = this.scheduleTourService.countSaleOffAdvertisements(agencyId); 
      if (page != null || size != null) {
         int sizeNo = size == null ? 10 : size.intValue();
         final int firstResult = page == null ? 0 : (page.intValue() - 1) * sizeNo;
         uiModel.addAttribute("saleoffs", this.scheduleTourService.findSaleOffAdvertisements(agencyId, firstResult, sizeNo));
         float nrOfPages = (float) count / sizeNo;
         uiModel.addAttribute("maxPages", (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages));
     } else {
         List<SaleOff> saleoffs = count == 0 ? new ArrayList<SaleOff>() : scheduleTourService.findSaleOffAdvertisements(agencyId, 0, 25);
         uiModel.addAttribute("saleoffs", saleoffs);
     }
      uiModel.addAttribute("agencyId", agencyId);
      return "touristAgency/saleoff/advertisement";
   }

   @RequestMapping(value="{agencyId}/advertisement/{saleoffId}", method = RequestMethod.GET)
   public String showAdvs(@PathVariable("agencyId")Long agencyId,@PathVariable("saleoffId")Long saleoffId, Model uiModel){
      uiModel.addAttribute("agencyId", agencyId);
      uiModel.addAttribute("selected", "advertisement");
      uiModel.addAttribute("selectedUrl", "/touristAgency/"+agencyId+"/advertisement/"+saleoffId+"/form");
      return "touristAgency/show";
   }

   @RequestMapping(value="{agencyId}/advertisement/{saleoffId}/form", method = RequestMethod.GET)
   public String showAdvsForm(@PathVariable("agencyId")Long agencyId,@PathVariable("saleoffId")Long saleoffId, Model uiModel){
      SaleOff saleOff = this.scheduleTourService.findSaleOff(saleoffId);
      uiModel.addAttribute("saleoff", saleOff);
      uiModel.addAttribute("agencyId", agencyId);
      return "touristAgency/saleoff/advertisement/show";
   }
   
   @RequestMapping(value="{agencyId}/advertisement/{saleoffId}/update", method = RequestMethod.GET)
   public String showUpdateAdvs(@PathVariable("agencyId")Long agencyId,@PathVariable("saleoffId")Long saleoffId, Model uiModel){
      uiModel.addAttribute("agencyId", agencyId);
      uiModel.addAttribute("selected", "advertisement");
      uiModel.addAttribute("selectedUrl", "/touristAgency/"+agencyId+"/advertisement/"+saleoffId+"/update/form");
      return "touristAgency/show";
   }

   @RequestMapping(value="{agencyId}/advertisement/{saleoffId}/update/form", method = RequestMethod.GET)
   public String showUpdateAdvsForm(@PathVariable("agencyId")Long agencyId,@PathVariable("saleoffId")Long saleoffId, Model uiModel, SessionStatus sessionStatus){
      SaleOff saleOff = this.scheduleTourService.findSaleOff(saleoffId);
      uiModel.addAttribute("saleoff", saleOff);
      Advertisement advertisement = null;
      if (uiModel.containsAttribute(SESSION_ERROROBJECTS) && uiModel.asMap().get(SESSION_ERROROBJECTS) != null){
         Model ssUIModel = (Model) uiModel.asMap().get(SESSION_ERROROBJECTS);
         uiModel.addAllAttributes(ssUIModel.asMap());
         Object sess = uiModel.asMap().get("advertisement");
         if (sess != null){
            advertisement = (Advertisement) sess;
         }
         sessionStatus.setComplete();
      }
      advertisement = advertisement == null ? saleOff.getAdvertisement() : advertisement;
      uiModel.addAttribute("advertisement", advertisement == null ? new Advertisement() : advertisement);
      uiModel.addAttribute("agencyId", agencyId);
      uiModel.addAttribute("prioritise", Arrays.asList(Priority.values()));
      return "touristAgency/saleoff/advertisement/update";
   }
   
   @RequestMapping(value="{agencyId}/advertisement/{saleoffId}", method = RequestMethod.PUT)
   public String updateAdvs(@PathVariable("agencyId")Long agencyId, @PathVariable("saleoffId")Long saleoffId,@Valid Advertisement advertisement, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest, SessionStatus sessionStatus) throws Exception {
      if (bindingResult.hasErrors()) {
         uiModel.addAttribute(SESSION_ERROROBJECTS, uiModel);
         return showUpdateAdvs(agencyId, saleoffId, uiModel);
      }
      
      uiModel.asMap().clear();
      sessionStatus.setComplete();
      SaleOff saleoff = this.scheduleTourService.findSaleOff(saleoffId);
      ScheduleTour scheduleTour = saleoff.getScheduleTour();
      advertisement.setModifiedDate(new Date(System.currentTimeMillis()));
      saleoff.setAdvertisement(advertisement);
      scheduleTour.setSaleOff(saleoff);
      this.scheduleTourService.saveScheduleTour(scheduleTour);
      return "redirect:/touristAgency/"+encodeUrlPathSegment(agencyId.toString(), httpServletRequest)+"/advertisement";
   }

   @RequestMapping(value="{agencyId}/advertisement/{saleoffId}", method = RequestMethod.DELETE)
   public String deleteAdvs(@PathVariable("agencyId")Long agencyId,  @PathVariable("saleoffId")Long saleoffId,Model uiModel,HttpServletRequest httpServletRequest) throws Exception {
      SaleOff saleoff = this.scheduleTourService.findSaleOff(saleoffId);
      ScheduleTour scheduleTour = saleoff.getScheduleTour();
      saleoff.setAdvertisement(null);
      scheduleTour.setSaleOff(saleoff);
      this.scheduleTourService.saveScheduleTour(scheduleTour);
      return "redirect:/touristAgency/"+encodeUrlPathSegment(agencyId.toString(), httpServletRequest)+"/advertisement";
   }
   
   void validate(CommonsMultipartFile commonsMultipartFile,Model uiModel, Errors errors) throws IOException{
      if (commonsMultipartFile.getSize() > 0){
         InputStream inputStream = commonsMultipartFile.getInputStream();
         if (!MimeTypeSupport.supportMineType(commonsMultipartFile.getContentType())){
            errors.reject("error_fileData_contenttype");
         }
         if (commonsMultipartFile.getSize() > FileInfoUtil.DEFAULT_BUFFER_SIZE){
            errors.reject("error_fileData_large");
         }
         if (!errors.hasFieldErrors("fileData")){
            Dimension dimension = SimpleImageInfo.processStream(inputStream);
            if (dimension.getWidth() < 200){
               errors.reject("error_fileData_limit_width");
            }
         }
      }
   }
   
   void populateEditForm(Model uiModel, Business business) {
      uiModel.addAttribute("agency", business);
      List<CommonItems> countries = commonItemsService.findAllCountrys();
      countries.add(0, new CommonItems());
      uiModel.addAttribute("countries", countries);
      uiModel.addAttribute("cities", commonItemsService.findAllCitys());
   }

   void populateTourEditForm(Model uiModel, ScheduleTour scheduleTour) {
      uiModel.addAttribute("tour", scheduleTour);
      List<CommonItems> transports = commonItemsService.findAllTransports();
      transports.add(0, new CommonItems());
      uiModel.addAttribute("transports", transports);
   }
   
   void populateSaleOffEditForm(Model uiModel, SaleOff saleoff) {
      uiModel.addAttribute("saleoff", saleoff);
   }
   
   String encodeUrlPathSegment(String pathSegment, HttpServletRequest httpServletRequest) {
      String enc = httpServletRequest.getCharacterEncoding();
      if (enc == null) {
          enc = WebUtils.DEFAULT_CHARACTER_ENCODING;
      }
      try {
          pathSegment = UriUtils.encodePathSegment(pathSegment, enc);
      } catch (UnsupportedEncodingException uee) {}
      return pathSegment;
  }
}
